#pragma once
#include <string>
#include <vector>
#include <memory>
#include <optional>
#include "db_common.h"
enum class ColType { INT,FLOAT,DOUBLE,CHAR,VARCHAR,TEXT,BLOB,DATE,TIME,DATETIME,TIMESTAMP,BOOLEAN,JSON,TINYINT,SMALLINT,BIGINT };



struct Stmt { virtual ~Stmt() {} };


struct InsertStmt : Stmt {
    std::string table;
    std::vector<std::string> colNames;

    enum class ValType { INT, FLOAT, DOUBLE, STRING, BOOL, DATE, TIME, DATETIME, TIMESTAMP, JSON, NULLTYPE };

    struct Val {
    ValType type;
    int i = 0;
    double d = 0.0;
    bool b = false;
    std::string s;
    std::string asString() const {
        switch (type) {
        case ValType::INT:     return std::to_string(i);
        case ValType::FLOAT:{
            std::ostringstream oss;
            oss << std::setprecision(7) << d; // 保留更多精度
            return oss.str();
        }
        case ValType::DOUBLE: {
            std::ostringstream oss;
            oss << std::setprecision(15) << d; // 保留更多精度
            return oss.str();
        }
        case ValType::BOOL:    return b ? "TRUE" : "FALSE";
        case ValType::STRING:
        case ValType::DATE:
        case ValType::TIME:
        case ValType::DATETIME:
        case ValType::JSON:
        case ValType::TIMESTAMP:
            return "'" + s + "'";
        default:
            return "NULL";
        }
    }
};

    std::vector<Val> values;
};

struct SelectStmt : Stmt {
    std::vector<std::string> proj;
    std::string table;
    std::unique_ptr<Condition> where;

    std::vector<OrderBy> orderBy;  
    std::optional<int> limit;
    std::optional<int> offset;         
};

struct DeleteStmt : Stmt
{
	std::string table;
	std::unique_ptr<Condition> where;
};
struct DropTableStmt : Stmt
{
	std::string table;
};


struct UpdateStmt : Stmt {
    std::string table;  // 要更新的表
    std::unordered_map<std::string, Value> assigns; 
    // 列名 = 值，值保持字符串形式，执行时再解析

    std::unique_ptr<Condition> where; // WHERE 条件，可为空
};

struct CreateIndexStmt : Stmt
{
	std::string index_name;
	std::string table;
	std::vector<std::string> cols;
	bool unique = false;
};

struct DropIndexStmt : Stmt
{
    std::string table;
	std::string index_name;
};
struct ShowTablesStmt : Stmt
{
};
struct ShowIndicesStmt : Stmt
{
	std::string table; // SHOW INDICES FROM table
};
struct ColumnDef {
    std::string name;
    ColType t;
    int len = 0;
    bool nullable = true;
    bool unique = false;
    bool primary = false;
    bool auto_increment = false;
    bool isUnsigned = false;
    std::optional<InsertStmt::Val> default_value;
    std::string comment;
    
};struct CreateTableStmt : Stmt {
    std::string name;
    std::vector<ColumnDef> cols;
};struct AlterTableStmt : Stmt {
    std::string table;
    std::string action;   // "ADD_COLUMN", "DROP_COLUMN", "MODIFY_COLUMN", "CHANGE_COLUMN", "RENAME_TABLE", "MODIFY_COMMENT"

    ColumnDef colDef;     // 新列定义（ADD/MODIFY/CHANGE）
    std::string oldName;  // 旧列名（DROP/CHANGE/RENAME COLUMN）
    std::string newName;  // 新列名（CHANGE/RENAME TABLE）
    std::string newComment; // 新表注释（COMMENT）
};